﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.OleDb;
using System.Data;
using System.Diagnostics.Contracts;

namespace Numero1DataReader
{
    public class ConnexionDB : IDisposable
    {
        private const string CHAINE_CONNEXION = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=cours.mdb";
        private static ConnexionDB maConnexion;
        private OleDbConnection oleConnexion;

        public OleDbConnection OleConnexion
        {
            get { return oleConnexion; }
        }

        public static ConnexionDB Creer()
        {
            Contract.Requires(!String.IsNullOrEmpty(CHAINE_CONNEXION), "La chaîne de connexion doit être définie.");
            Contract.Ensures(maConnexion.oleConnexion != null, "Erreur à la création de la connexion.");

            if (maConnexion == null)
            {
                maConnexion = new ConnexionDB();
                maConnexion.oleConnexion = new OleDbConnection(CHAINE_CONNEXION);
            }
            return maConnexion;
        }

        public static void Detruire()
        {
            Contract.Ensures(maConnexion == null, "Erreur à la destruction de la connexion.");

            if (maConnexion != null && maConnexion.oleConnexion.State == System.Data.ConnectionState.Open)
            {
                maConnexion.Dispose();
            }
        }

        public int ExecuterScalaire(string commande)
        {
            Contract.Requires(OleConnexion != null, "La connexion doit être définie pour exécuter une requête");

            int resultat;
            oleConnexion.Open();
            OleDbCommand maCmd = new OleDbCommand(commande, oleConnexion);
            resultat = (int)maCmd.ExecuteScalar();
            oleConnexion.Close();
            return resultat;
        }

        public List<Dictionary<string, object>> ExecuterReader(string commande, List<OleDbParameter> parametres = null)
        {
            Contract.Requires(OleConnexion != null, "La connexion doit être définie pour exécuter une requête");

            List<Dictionary<string, object>> listeRetour = new List<Dictionary<string, object>>();
            OleDbDataReader reader;
            oleConnexion.Open();
            OleDbCommand maCmd = new OleDbCommand(commande, oleConnexion);

            if (parametres != null)
            {
                foreach(OleDbParameter parametre in parametres)
                {
                    maCmd.Parameters.Add(parametre);
                }
            }

            reader = maCmd.ExecuteReader();
            while (reader.Read())
            {
                Dictionary<string, object> dictionnaireDansListe = new Dictionary<string, object>();
                listeRetour.Add(dictionnaireDansListe);

                for (int ctr = 0; ctr < reader.FieldCount; ctr++)
                {
                    dictionnaireDansListe.Add(reader.GetName(ctr), reader[ctr]);
                }
            }

            maConnexion.oleConnexion.Close();
            return listeRetour;
        }

        public void Dispose()
        {
            GC.SuppressFinalize(this);
        }
    }
}
